package com.chenl.provider.DEMOS.定时任务.aop;

import com.chenl.provider.util.RedisLock;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Slf4j
@Aspect
@Component
public class ScheduledAspect {
    @Autowired
    RedisLock redisLock;

    /**
     * 定时任务统一添加分布式锁
     *
     */
    @Around("@annotation(org.springframework.scheduling.annotation.Scheduled)")
    public Object JobAspectMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String classPathName = signature.getMethod().getDeclaringClass().getName();
        String methodName = signature.getMethod().getName();
        log.info("定时器Aspect---开始执行:{}", classPathName + "_" + methodName);
        Boolean flag = redisLock.lock(classPathName + "_" + methodName, 15L, TimeUnit.SECONDS);
        Object proceed = null;
        if (flag) {
            try {
                proceed = joinPoint.proceed();
            } catch (Throwable e) {
                log.error("定时器Aspect---定时器执行出现异常:{}", e.toString());
                e.printStackTrace();
            } finally {
                //考虑不同机器时间误差,不要马上解锁
                TimeUnit.MILLISECONDS.sleep(1000L);
                redisLock.unlock(classPathName + "_" + methodName);
            }
        } else {
            log.info("定时器Aspect---跳过此次执行:{}", classPathName + "_" + methodName);
        }
        return proceed;
    }
}